home *** CD-ROM | disk | FTP | other *** search
/ Danny Amor's Online Library / Danny Amor's Online Library - Volume 1.iso / html / faqs / faq / databases / foxpro.misc < prev    next >
Encoding:
Text File  |  1995-07-25  |  18.3 KB  |  547 lines

  1. Subject: FoxPro Databases FAQ #3: Things Your Mamma Never Told You.
  2. Newsgroups: comp.databases.xbase.fox,comp.answers,news.answers
  3. From: kcochran@nyx10.cs.du.edu (Keith "Justified And Ancient" Cochran)
  4. Date: 2 Nov 1994 00:49:50 -0700
  5.  
  6. Archive-name: databases/foxpro/misc
  7. Posting-frequency: monthly
  8.  
  9. [This is FAQ version 1.0.0.5 - Last Updated 09/18/94.  New sections or
  10. altered text are marked with ">" in the left hand column.]
  11.  
  12. This FAQ assumes that you have anything from a passing knowledge of xBase
  13. languages in general to an intense knowledge of FoxPro event programming
  14. in C.
  15.  
  16. Sections in this FAQ are seperated with "*****", but are not numbered,
  17. because the FAQ itself is in alphabetical order based on title.  If
  18. you have discovered a new trick in FoxPro, feel free to submit it to
  19. me at kcochran@nyx.cs.du.edu.
  20.  
  21. EDITORIAL DISCLAIMER:  I have taken the liberty of editing the entries
  22. in this FAQ slightly.  Mostly, I have reworded the occasional awkward
  23. sentence, and done such cosmetic changes as putting all FoxPro commands
  24. in ALL CAPS, reworded them into FoxPro format (i.e SELECT - SQL instead
  25. of an SQL SELECT statement), and other such stuff.
  26.  
  27. POLICY DISCLAIMER:  Most of the information in this FAQ is unsupported
  28. by Microsoft.  I make no guarantees of any sort about the information
  29. contained in this FAQ.  If you use something you find here and wind up
  30. clobbering all your data, it's your problem, not mine.
  31.  
  32. WHAT'S IN THIS FAQ:
  33.  
  34. Abnormal Program Termination in Extended FoxPro
  35.    kruckenb@sal.cs.utah.edu (Joseph Kruckenberg)
  36.  
  37. Diagonal Lines In FoxPro/Windows
  38.    blank@silver.ucs.indiana.edu (Doug Blank)
  39.  
  40. Generating Complex Indexes On Numeric Fields
  41.  
  42. Getting Rid Of The Microsoft FoxPro Screen And Title
  43.  
  44. Outer Joins In FoxPro
  45.    davec@wsti.demon.co.uk (David Churcher)
  46.  
  47. Source Code Wanted - Only Singles Need Apply
  48.    martin@convext.csd.uwm.edu (Martin A. Miller)
  49.  
  50. Unsupported Trick To Get Blank (Not Zero) Fields
  51.    wsd@world.std.com (Rorschach)
  52.  
  53. Writable SQL Cursors!
  54.    lotridge@charlie.ccd.bnl.gov (Charlie Lotridge)
  55.  
  56. *****
  57. Abnormal Program Termination in Extended FoxPro
  58.    kruckenb@sal.cs.utah.edu (Joseph Kruckenberg)
  59.  
  60. So, you're running along in the Extended Version of FoxPro when all
  61. of a sudden you see:
  62.  
  63. abnormal program termination: page fault. cs:eip=000ch:0007791fh
  64.  
  65. (Note:  cs:eip may point to pretty much anywhere.  If you don't know
  66. 386 assembler, don't worry about what the numbers mean.)
  67.  
  68. Now what?  You can fire FoxPro back up and hope and pray that it doesn't
  69. happen again, or you can add the following line to your AUTOEXEC.BAT
  70. file:
  71.  
  72. SET FOXPROX=-saveregs
  73.  
  74. (Note:  No spaces between the equals and minus signs.)
  75.  
  76. This command tells FoxPro to preserve any registers in use and not to
  77. overwrite them while running (given the limited explanation I recieved).
  78.  
  79. *****
  80. Diagnoal Lines In FoxPro/Windows
  81.    blank@silver.ucs.indiana.edu (Doug Blank)
  82.  
  83. Is there any way to draw lines that are neither horizontal or vertical in
  84. FoxPro?  I am trying to make line graphs from data without using Microsoft
  85. Graph. Any ideas?
  86.  
  87. Yes, it is sad but true: you cannot draw a diagonal line. I did try
  88. dropping down to the windows API, and you can in fact draw any thing
  89. that you want in the fox window --- but Fox doesn't "know" about it.
  90. Therefore, if you close the window and reopen it your line is gone.
  91. Any time that you cover your line, it won't be redrawn.
  92.  
  93. So, I finally ended up with the solution below. It does a pretty good
  94. job on arbitrary lines. You may have to adjust x and y dotsize. These
  95. parameters exist because of translation problems from real-valued
  96. points to screen coordinates (welcome to the world of GUI's!)
  97.  
  98. To use, call with:
  99.  
  100. =drawline(1,5,11,30,.T.) && to produce a color line from @ 1,5 to 11,30 or
  101. =drawline(1,5,11,30)     && to produce a black line 
  102.  
  103. Using this method, you can draw circles, splines, etc. Put the
  104. function below in your program, or comment out the first line and
  105. place in a file named DRAWLINE.PRG. It's not real fast nor smooth,
  106. but it works. You probably can't make the line any thinner due to
  107. related problems with real-valued vs. screen coordinates, so pensize
  108. and penlength probaly can't be changed. You can change the RGB()
  109. funtion to make any colors you want, or even add a CASE statement to
  110. do them all, add shadows, etc.
  111.  
  112. FUNCTION drawline
  113. PARAMETER x1,y1,x2,y2,color
  114. PRIVATE x,y,B,slope
  115. #DEFINE xdotsize (.2)
  116. #DEFINE ydotsize (.5)
  117. #DEFINE pensize (3)
  118. #DEFINE penlen (.7)
  119. IF m.y1 = m.y2 && vertical line
  120.    IF x1 < x2
  121.       IF color
  122.          @m.x1,m.y1 to m.x2,m.y1 pen pensize color ;
  123.             RGB(0,255,0,255,255,255) style "T"
  124.       ELSE
  125.          @m.x1,m.y1 to m.x2,m.y1 pen pensize color ;
  126.             RGB(255,0,255,255,255,255) style "T"
  127.       ENDIF
  128.    ELSE
  129.       IF color
  130.          @m.x2,m.y1 to m.x1,m.y1 pen pensize color ;
  131.             RGB(0,255,0,255,255,255) style "T"
  132.       ELSE
  133.          @m.x2,m.y1 to m.x1,m.y1 pen pensize color ;
  134.             RGB(255,0,255,255,255,255) style "T"
  135.       ENDIF
  136.    ENDIF
  137. ELSE
  138.    m.slope = (m.x1 - m.x2)/(m.y1 - m.y2)
  139.    m.B = m.x1 - (m.slope * m.y1)
  140.    IF ABS((m.x1 - m.x2) / xdotsize) > ABS((m.y1 - m.y2) / ;
  141.       ydotsize)
  142.       FOR m.x = m.x1 TO m.x2 STEP xdotsize * ;
  143.          IIF( m.x1 > m.x2, -1, 1)
  144.             m.y = (m.x - m.B) / m.slope
  145.             IF color
  146.                @m.x,m.y to m.x,m.y+penlen pen ;
  147.                   pensize color RGB(0,255,0,255,255,255) ;
  148.                   style "T"
  149.             ELSE
  150.                @m.x,m.y to m.x,m.y+penlen pen ;
  151.                   pensize color RGB(255,0,255,255,255,255) ;
  152.                   style "T"
  153.             ENDIF
  154.       ENDFOR
  155.    ELSE
  156.       FOR m.y = m.y1 TO m.y2 STEP ydotsize * IIF( m.y1 > ;
  157.          m.y2, -1, 1)
  158.          m.x = (m.slope * m.y) + m.B
  159.          IF color
  160.             @m.x,m.y to m.x,m.y+penlen pen ;
  161.                pensize color RGB(0,255,0,255,255,255);
  162.                style "T"
  163.          ELSE
  164.             @m.x,m.y to m.x,m.y+penlen pen ;
  165.                pensize color RGB(255,0,255,255,255,255) ;
  166.                style "T"
  167.          ENDIF
  168.       ENDFOR
  169.    ENDIF
  170. ENDIF
  171. RETURN
  172.  
  173. *****
  174. Generating Complex Indexes On Numeric Fields
  175.  
  176. There's an interesting "feature" that the FoxPro manuals don't tell
  177. you about in the information on indexes.  Let's say you have a database:
  178. ACCOUNT N(6,0)
  179. SSN N(9,0)
  180.  
  181. On first glance, if you wanted to sort the database by social security
  182. number, and then account, you can just:
  183.  
  184. INDEX ON SSN+ACCOUNT TAG myorder
  185. SET ORDER TO myorder
  186.  
  187. This, of course, doesn't work.  What happens is that FoxPro just adds
  188. the values together, causing:
  189.  
  190. SSN = 076541111 ACCOUNT = 999999 (Key value = 77541110)
  191.  
  192. To appear AFTER
  193.  
  194. SSN = 076541122 ACCOUNT = 000333 (Key value = 76541455)
  195.  
  196. Note:  Microsoft assures me that this problem doesn't occur if you are
  197. working with N(x,y > 1) fields, date fields, or logical fields.
  198.  
  199. What can you do to sort properly?  There are several schools of thought:
  200.  
  201. (1)You can add a digit after the decimal point.  Microsoft assures me
  202.    that this will solve the problem.
  203.  
  204. (2)If you're working with fixed length fields, you can shift one set
  205.    of digits over so that your math is correct.  In the above example,
  206.    you would want to:
  207.    INDEX ON ssn*1000000+account TAG myorder
  208.  
  209. (3)Convert the numerics into strings, and concatenate them:
  210.    INDEX ON STR(ssn)+STR(account) TAG myorder
  211.  
  212.    or:
  213.  
  214.    INDEX ON TRANSFORM(ssn,"#########")+TRANSFORM(account,"######") TAG myorder
  215.  
  216. *****
  217. Getting Rid Of The Microsoft FoxPro Screen And Title
  218.  
  219. The first thing to do if you're tired of seeing "Microsoft FoxPro"
  220. every time you start your application is to use the -T command line
  221. option to prevent it from showing up.  This looks like this:
  222.  
  223. FOX -T
  224.  
  225. If you're using FoxPro/Windows or FoxPro/MAC, and want to get rid of
  226. the "Microsoft FoxPro" title in the bar of the main screen, you can
  227. do several things.  After your application starts, you can
  228.  
  229. MODIFY WINDOW ... TITLE "My Title"
  230.  
  231. (Anybody know what the window's called?)
  232.  
  233. and the window name will change to whatever your title is.
  234.  
  235. You can also put the following line in your config.fpw/config.fpm
  236. file:
  237.  
  238. Title=My Title
  239.  
  240. Note the lack of quotes.  This will cause the main window to be listed
  241. as "My Title" as soon as FoxPro starts up.  For some reason, there are
  242. differences in the way this works depending on whether you are running
  243. your application from the development kit or the distribution kit.
  244.  
  245. *****
  246. Outer Joins In FoxPro
  247.    davec@wsti.demon.co.uk (David Churcher)
  248.  
  249. I give up, I RTFM (and I got FAQ'd) and did not find the syntax.
  250.  
  251. Using the foxpro Select command, I wish to join two or more tables 
  252. inclusivley. By this I mean :
  253.  
  254.         To join Table A and B, if there is no join then include the
  255.         records from table A and place blanks in the fields from table B.
  256.  
  257. In previous versions of foxpro I would have used "Set relation to" and 
  258. it would have just happened.
  259.  
  260. Oh no, it's the dreaded Left Outer Join! This is an SQL construct which 
  261. FoxPro doesn't currently support, so you have to simulate it using a 
  262. UNION of two selects: one for all the records with matches in table B, 
  263. and one for all the records without. Here's an example:
  264.  
  265. SELECT a.keyfield, ;
  266.        a.datafield1, ;
  267.        b.datafield2, ;
  268.        b.datafield3 ;
  269.    FROM a,b ;
  270.    WHERE a.keyfield = b.keyfield ;
  271.    UNION ;
  272.       SELECT a.keyfield, ;
  273.              a.datafield1, ;
  274.              000.00, ;
  275.              000.00 ;
  276.          FROM a ;
  277.          WHERE a.keyfield NOT IN ;
  278.             (SELECT b.keyfield ;
  279.                 FROM b)
  280.  
  281. Couple of points:
  282.  
  283. 1. The numeric and string constants in the second SELECT (000.00 in this
  284. example) have to exactly match the length of the fields in the second
  285. database, because FoxPro requires both sides of a UNION to exactly the
  286. same structure.
  287.  
  288. 2. SET RELATION TO and SET SKIP TO may be faster and easier if it's only
  289. a simple query.
  290.  
  291. ****
  292. Source Code Wanted - Only Singles Need Apply
  293.    martin@convext.csd.uwm.edu (Martin A. Miller)
  294.  
  295. There are two companies who provide software to generate source code
  296. from compiled Fox* applications/programs.
  297.  
  298. 1) Xitech Inc. 
  299.    Toledo, Ohio (407) 292-8629; FAX: (407) 292-8652
  300.    Product name: ReFox
  301.    Restores FoxBASE, FoxBASE+, FoxPro 1.x, FoxPro 2.0,
  302.    FoxPro 2.5 (including Windows).
  303.    Cost: $299 + S&H
  304.  
  305. 2) HILCO Software
  306.    Sebastopol, CA (707) 829-5011; FAX: (707) 829-5710
  307.    Product Names: dCRYPTR for dBASE III Run-Time
  308.                   DECODE for dBASE II Run-Time
  309.                   deFOX for FoxBase II (early dBASE II compatible)
  310.                   OutFOX for Foxbase+
  311.    Cost: $149.95 + $5.00 S&H
  312.  
  313. In addition, Ron Talmadge made me aware of the following:
  314.    Frx2Prg Version 2.5
  315.    Have it your way with FoxPro Reports
  316.    Rory Data International
  317.    17 Thorburn Road
  318.    North Potomac, MD 20878
  319.    Phone: (301) 251-0497
  320.    BBS: 301-251-9206
  321.    FAX: 301-258-6862
  322.    CIS: 73765,121
  323.  
  324.    Frx2Prg is a utility that translates a FoxPro 2.0 or 2.5 report
  325.    format (.FRX) file into a corresponding program (.PRG) file.
  326.  
  327. *****
  328. Unsupported Trick To Get Blank (Not Zero) Fields
  329.    wsd@world.std.com (Rorschach)
  330.  
  331. I been pulling my hair out for hours trying to figure this out.  Is is
  332. possible to exclude records from an average that are blank?
  333.  
  334. DOCUMENT:Q97647  14-DEC-1993  [B_WFOXPRO]
  335. TITLE   :INF: How Exclude Blanks, but Not Zeros, from an Average
  336. PRODUCT :FoxPro For Windows
  337. PROD/VER:2.50 2.50a | 2.00 2.50 2.50a
  338. OPER/SYS:WINDOWS    | MS-DOS
  339. KEYWORDS:
  340.  
  341. --------------------------------------------------------------------
  342. The information in this article applies to:
  343.  
  344.  - Microsoft FoxPro for Windows, versions 2.5 and 2.5a
  345.  - Microsoft FoxPro for MS-DOS, versions 2.0, 2.5, and 2.5a
  346. --------------------------------------------------------------------
  347.  
  348. SUMMARY
  349. =======
  350.  
  351. FoxPro's AVERAGE command sums numeric fields and divides the summed result
  352. by the number of records summed. In some cases, you may want to determine
  353. the AVERAGE only for fields that are not blank. Since there is no command
  354. in the FoxPro language that can distinguish between a numeric field that is
  355. blank and one that contains a zero, you must write a user-defined function
  356. similar to the one below in order to accomplish this task.
  357.  
  358. MORE INFORMATION
  359. ================
  360.  
  361. The following function requires two parameters, the database name and field
  362. name. An example of calling this function is as follows:
  363.  
  364.   ave = ave_nobl("test","num")
  365.  
  366. The above command shows "test" as the name of the database file and "num"
  367. as the numeric field to be averaged.
  368.  
  369. Sample Code
  370. -----------
  371.  
  372.    FUNCTION ave_nobl
  373.  
  374.    PARAMETERS dbfname,fld_name
  375.    PRIVATE blank,skipbytes,i,numofblanks
  376.    skipbytes=0
  377.    numofblanks=0
  378.  
  379.    IF USED(dbfname)
  380.       SELECT (dbfname)
  381.    ELSE
  382.       SELECT 0
  383.       USE (dbfname)
  384.    ENDIF
  385.  
  386.    headersize = HEADER(dbfname)
  387.    no_records = RECCOUNT()
  388.    rec_size   = RECSIZE()
  389.    fld_width  = FSIZE(fld_name)
  390.  
  391.    * Place the database structure information in an array to
  392.    * determine the field's position. The position is equal to
  393.    * the row number of the field in the array, which is returned
  394.    * by ASUBSCRIPT().
  395.  
  396.    =afields(afld_pos)
  397.    fld_pos = ASUBSCRIPT(afld_pos,ASCAN(afld_pos,UPPER(fld_name)),1)
  398.  
  399.    FOR i=1 TO (fld_pos-1)
  400.       skipbytes=skipbytes+FSIZE(FIELD(i))
  401.    ENDFOR
  402.    USE
  403.  
  404.    blank = REPLICATE(" ",fld_width)
  405.  
  406.    m.file = FOPEN(dbfname+".dbf")
  407.  
  408.    IF m.file<0
  409.       RETURN "Error opening database "+dbfname+"."
  410.    ELSE
  411.       * The numeric field begins on the first byte following the
  412.       * header and any preceding fields (headersize+skipbytes+1).
  413.  
  414.       m.move = FSEEK(m.file,headersize+skipbytes+1)
  415.  
  416.       * Read the value of the numeric field and compare it to
  417.       * the variable blank.
  418.  
  419.       m.num  = FREAD(m.file,fld_width)
  420.  
  421.       DO WHILE .NOT. FEOF(m.file)
  422.          IF m.num = blank
  423.             numofblanks = numofblanks+1
  424.          ENDIF
  425.  
  426.          * Move to the beginning of the numeric field in the next
  427.          * record, read the next value, and compare it to the variable
  428.          * blank.
  429.  
  430.          m.move = FSEEK(m.file,(rec_size-fld_width),1)
  431.          m.num  =   FREAD(m.file,fld_width)
  432.       ENDDO
  433.       m.move = FCLOSE(m.file)
  434.  
  435.       USE (dbfname)
  436.       SUM EVAL(fld_name) TO sub_result
  437.       USE
  438.  
  439.       * Divide the sum by the number of records that are not blank.
  440.  
  441.       result = sub_result/(no_records-numofblanks)
  442.  
  443.       * Return the result to the program that called ave_nobl().
  444.  
  445.       RETURN result
  446.    ENDIF
  447.  
  448. Additional reference words: 2.00 2.50 2.50a null blank
  449.  
  450. =============================================================================
  451.  
  452. THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS
  453. PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.  MICROSOFT DISCLAIMS
  454. ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES
  455. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO
  456. EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR
  457. ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL,
  458. CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF
  459. MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE
  460. POSSIBILITY OF SUCH DAMAGES.  SOME STATES DO NOT ALLOW THE EXCLUSION
  461. OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES
  462. SO THE FOREGOING LIMITATION MAY NOT APPLY.
  463.  
  464. Copyright Microsoft Corporation 1993.
  465.         
  466. *****
  467.    Writable SQL Cursors!
  468.       By Charlie Lotridge (lotridge@charlie.ccd.bnl.gov)
  469.  
  470.    We've all had this problem:  You go to extract some temporary
  471.    data from a few tables using a SELECT - SQL statement.  You
  472.    set up the SELECT to output into a cursor so that you have
  473.    the flexibility and efficiency of a table without having to
  474.    be concerned about cleaning up after yourself.  THen you decide
  475.    you'd like to add a record to this cursor or change a value in
  476.    it and BOOM! - "Cannot Write To A Read-Only File".
  477.  
  478.    So what do you do?  In one of their FastTips, Microsot suggests
  479.    that you first do your SELECT into an array, then create your
  480.    cursor with the same structure, and finally use the APPEND FROM
  481.    ARRAY command to move the data into the cursor.  For example:
  482.  
  483.    SELECT cust_name ;
  484.       FROM customers ;
  485.       INTO ARRAY temp
  486.    CREATE CURSOR cust_curs ;
  487.       (cust_name C(30))
  488.    SELECT cust_curs
  489.    APPEND FROM ARRAY temp
  490.    RELEASE temp
  491.  
  492.    But this solution is less than ideal for at least two reasons
  493.    that I can think of.  First, the cost in memory for the array
  494.    can be quite large if the SELECT - SQL statement generates a
  495.    lot of data.
  496.  
  497.    The second reason is more substantial - you must know the exact
  498.    structure of the data being generated by the SELECT; both the
  499.    order of the fields and their respective sizes.  This is at
  500.    best an inconvenience, since if you change the structure of any
  501.    of the source DBF's, you may also have to change the program
  502.    code, and at worst impossible if you're trying to write some
  503.    generalized routine which doesn't know much about the data
  504.    it is operating on.
  505.  
  506.    [Question from the peanut gallery:  Can't you COPY STRUCTURE TO
  507.     ARRAY, and then create your cursor from that array?]
  508.  
  509.    So what's the solution?  It's simple, really.  I came upon this
  510.    idea when I was trying to change the alias of a cursor (don't
  511.    ask why).
  512.  
  513.    At the temporary expense of an extra work area, you can rename
  514.    the alias of your cursor (or any open table for that matter) and
  515.    at the same time make it writable!!!  For example:
  516.  
  517.    PROCEDURE rename_table
  518.    PARAMETERS m.fromalias, m.toalias
  519.       * Open the table in another work area. *
  520.       USE (dbf(m.fromalias)) IN 0 ALIAS (m.toalias) AGAIN
  521.  
  522.       * Close the old alias. *
  523.       USE IN (m.fromalias)
  524.  
  525.       * And you're done! *
  526.    RETURN
  527.  
  528.    And that's all there is to it.  The beauty of this solution is that
  529.    your cursor's new alias has all the appearances of a regular DBF
  530.    (it shows up in all caps in the View Window, and you can even use
  531.    the SETUP button on it), yet it retains that most attractive quality
  532.    of a cursor - it goes away when you close it!
  533.  
  534.    If the original alias or workarea of the cursor is important for some
  535.    reason, with a little extra work rename_table can be make to preserve
  536.    these characteristics with no loss of functionality.
  537.  
  538.    ***WARNING*** In some circumstances, the cursor you create is actually
  539.    ***WARNING*** just a view of the table, not a seperate table in itself.
  540.    ***WARNING*** In this case, appending, deleting, or altering records
  541.    ***WARNING*** in your "cursor" will also alter data in the database.
  542. -- 
  543. =kcochran@nyx.cs.du.edu | B(0-4) c- d- e++ f- g++ k(+) m r(-) s++(+) t | TSAKC=
  544. =My thoughts, my posts, my ideas, my responsibility, my beer, my pizza.  OK???=
  545. =                          "Love can break your heart"                        =
  546.  
  547.